package com.zerlings.gabeisfaker.ui

import android.view.View
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder

abstract class BaseAdapter<T, TBinding: ViewDataBinding>(private val brId: Int, layoutId: Int, dataList: MutableList<T>?) : BaseQuickAdapter<T, BaseViewHolder>(layoutId, dataList) {

    private var onItemClickListener: ((BaseAdapter<T, TBinding>, View, Int, T) -> Unit)? = null

    private var onItemLongClickListener: ((BaseAdapter<T, TBinding>, View, Int, T) -> Boolean)? = null

    private var onItemChildClickListener: ((BaseAdapter<T, TBinding>, View, Int, T) -> Unit)? = null

    private var onItemChildLongClickListener: ((BaseAdapter<T, TBinding>, View, Int, T) -> Boolean)? = null

    protected open fun setOnItemClick(view: View, position: Int, item: T) {
        onItemClickListener?.invoke(this, view, position, item)
    }

    protected open fun setOnItemLongClick(view: View, position: Int, item: T): Boolean {
        return onItemLongClickListener?.invoke(this, view, position, item) ?: false
    }

    protected open fun setOnItemChildClick(view: View, position: Int, item: T) {
        onItemChildClickListener?.invoke(this, view, position, item)
    }

    protected open fun setOnItemChildLongClick(view: View, position: Int, item: T): Boolean {
        return onItemChildLongClickListener?.invoke(this, view, position, item) ?: false
    }

    fun setOnItemClickListener(listener: (BaseAdapter<T, TBinding>, View, Int, T) -> Unit) {
        onItemClickListener = listener
    }

    fun setOnItemLongClickListener(listener: (BaseAdapter<T, TBinding>, View, Int, T) -> Boolean) {
        onItemLongClickListener = listener
    }

    fun setOnItemChildClickListener(listener: (BaseAdapter<T, TBinding>, View, Int, T) -> Unit) {
        onItemChildClickListener = listener
    }

    fun setOnItemChildLongClickListener(listener: (BaseAdapter<T, TBinding>, View, Int, T) -> Boolean) {
        onItemChildLongClickListener = listener
    }

    override fun bindViewClickListener(viewHolder: BaseViewHolder, viewType: Int) {
        onItemClickListener?.let {
            viewHolder.itemView.setOnClickListener { v ->
                var position = viewHolder.adapterPosition
                if (position == RecyclerView.NO_POSITION) {
                    return@setOnClickListener
                }
                position -= headerLayoutCount
                setOnItemClick(v, position, getItem(position))
            }
        }
        onItemLongClickListener?.let {
            viewHolder.itemView.setOnLongClickListener { v ->
                var position = viewHolder.adapterPosition
                if (position == RecyclerView.NO_POSITION) {
                    return@setOnLongClickListener false
                }
                position -= headerLayoutCount
                setOnItemLongClick(v, position, getItem(position))
            }
        }

        onItemChildClickListener?.let {
            for (id in getChildClickViewIds()) {
                viewHolder.itemView.findViewById<View>(id)?.let { childView ->
                    if (!childView.isClickable) {
                        childView.isClickable = true
                    }
                    childView.setOnClickListener { v ->
                        var position = viewHolder.adapterPosition
                        if (position == RecyclerView.NO_POSITION) {
                            return@setOnClickListener
                        }
                        position -= headerLayoutCount
                        setOnItemChildClick(v, position, getItem(position))
                    }
                }
            }
        }
        onItemChildLongClickListener?.let {
            for (id in getChildLongClickViewIds()) {
                viewHolder.itemView.findViewById<View>(id)?.let { childView ->
                    if (!childView.isLongClickable) {
                        childView.isLongClickable = true
                    }
                    childView.setOnLongClickListener { v ->
                        var position = viewHolder.adapterPosition
                        if (position == RecyclerView.NO_POSITION) {
                            return@setOnLongClickListener false
                        }
                        position -= headerLayoutCount
                        setOnItemChildLongClick(v, position, getItem(position))
                    }
                }
            }
        }
    }

    override fun onItemViewHolderCreated(viewHolder: BaseViewHolder, viewType: Int) {
        DataBindingUtil.bind<TBinding>(viewHolder.itemView)
    }

    final override fun convert(helper: BaseViewHolder, item: T) = convert(helper, item, helper.layoutPosition)

    final override fun convert(helper: BaseViewHolder, item: T, payloads: List<Any>) = convert(helper, item, helper.layoutPosition, payloads)

    protected open fun convert(holder: BaseViewHolder, item: T, position: Int) {
        holder.getBinding<TBinding>()?.apply {
            setVariable(brId, item)
            executePendingBindings()
        }
    }

    protected open fun convert(holder: BaseViewHolder, item: T, position: Int, payloads: List<Any>) {}

}